home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / RTF / xtextview.C < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  398 lines

  1. /* $Header: /usr/people/pcd/Src/RTF/RCS/xtextview.C,v 1.1 92/11/23 12:58:57 pcd Exp Locker: pcd $
  2.  */
  3.  
  4. #include "xtextview.h"
  5. extern "C" {
  6. #include "xtextview_c.h"
  7. #include "image.h"
  8. };
  9.  
  10.  
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include <assert.h>
  14. #include <stdio.h>
  15.  
  16. /* This code is relatively stable. */
  17. #define DEBUG 0
  18. int debug_x = 0;
  19. #include "debug.h"
  20.  
  21. void*
  22. XTextView_create(Display* disp, void* widget)
  23. {
  24.   return new XTextView(*disp, widget);
  25. }
  26.  
  27. void
  28. XTextView_destroy(void* v)
  29. {
  30.   delete ((XTextView*)v);
  31. }
  32.  
  33. int
  34. XTextView_string(void* v, const char* s, int e)
  35. {
  36.   return ((XTextView*)v)->string(s, e);
  37. }
  38.  
  39. void
  40. XTextView_resize(void* v, int x, int y, int w, int h)
  41. {
  42.   ((XTextView*)v)->resize(x, y, w, h);
  43. }
  44.  
  45.  
  46. void
  47. XTextView_drawable(void* v, Drawable d, int depth)
  48. {
  49.   ((XTextView*)v)->drawable(d, depth);
  50. }
  51.  
  52.  
  53. void
  54. XTextView_render(void* v, int x, int y, int w, int h)
  55. {
  56.   ((XTextView*)v)->render(x, y, w, h);
  57. }
  58.  
  59. int
  60. XTextView_region(void* v, long first, long last, int x[4], int y[4])
  61. {
  62.   return ((XTextView*)v)->region(first, last, x, y);
  63. }
  64.  
  65. int
  66. XTextView_locate(void* v, long pos, int* top, int* bot)
  67. {
  68.   return ((XTextView*)v)->locate(pos, top, bot);
  69. }
  70.  
  71.  
  72. int
  73. XTextView_height(void* v)
  74. {
  75.   return ((XTextView*)v)->page_height();
  76. }
  77.  
  78. int
  79. XTextView_width(void* v)
  80. {
  81.   return ((XTextView*)v)->width();
  82. }
  83.  
  84. long
  85. XTextView_position(void* v, int x, int y)
  86. {
  87.   return ((XTextView*)v)->position(x, y);
  88. }
  89.  
  90. char*
  91. XTextView_plain_text(const char* rt, long q)
  92. {
  93.   return View::plain_text(rt, q);
  94. }
  95.  
  96. XTextView::XTextView(Display& d, void* widget)
  97. : View()
  98. {
  99.   display_ = &d;
  100.   drawable_ = 0;
  101.   widget_ = widget;
  102. }
  103.  
  104. XFontStruct*
  105. XTextView::font(char* spec) const
  106. {
  107.   return Widget_font(widget_, spec);
  108. }
  109.  
  110. GC
  111. XTextView::get_gc(unsigned long mask, XGCValues& v)
  112. {
  113.   return Widget_get_gc(widget_, mask, &v);
  114. }
  115.  
  116. void
  117. XTextView::free_gc(GC gc)
  118. {
  119.   Widget_free_gc(widget_, gc);
  120. }
  121.  
  122. Pixel
  123. XTextView::color(int red, int green, int blue) const
  124. {
  125.   return Widget_color(widget_, red, green, blue);
  126. }
  127.  
  128. void
  129. XTextView::text_flow(TextFlow& parent, TextPosition f, TextPosition l,
  130.              const CharacterFormat& cf)
  131. {
  132.   new XTextFlow(parent, f, l, *this, cf);
  133. }
  134.  
  135. void
  136. XTextView::text_char(TextFlow& parent, TextPosition f, TextPosition l, char c,
  137.              const CharacterFormat& cf)
  138. {
  139.   new XTextFlow(parent, f, l, *this, cf, c);
  140. }
  141.  
  142. void
  143. XTextView::new_line(TextFlow& parent, TextPosition f, TextPosition l,
  144.             Inches sa)
  145. {
  146.   new XNewLineFlow(parent, f, l, *this, sa);
  147. }
  148.  
  149. void
  150. XTextView::drawable(Drawable d, unsigned int depth)
  151. {
  152.   if(d != drawable()){
  153.     drawable_ = d;
  154.     depth_ = depth;
  155.     clear();
  156.   }
  157. }
  158.  
  159. void
  160. XTextView::clear()
  161. {
  162.   if(drawable())
  163.     XClearArea(display(), drawable(), 0, 0, 0, 0, 1);
  164. }
  165.  
  166. int
  167. XTextView::render(Coord x, Coord y, Coord w, Coord h)
  168. {
  169.   REQUIRE(drawable() && format(), return 0);
  170.   BRect r(x, y, w, h);
  171.   page_->render(r);
  172.   return 1;
  173. }
  174.  
  175.  
  176. int
  177. XTextView::region(TextPosition f, TextPosition l, Coord x[4], Coord y[4])
  178. {
  179.   REQUIRE(drawable() && format(), return 0);
  180.  
  181.   x[0] = bounds_.left();
  182.   x[3] = bounds_.right();
  183.  
  184.   assert(f<l);
  185.   x[1] = page_->locate(f, &y[0], &y[1]); // textrect::locate@@
  186.   x[2] = page_->locate(l, &y[2], &y[3]);
  187.  
  188.   return 1;
  189. }
  190.  
  191.  
  192. int
  193. XTextView::locate(TextPosition pos, int* top, int* bot)
  194. {
  195.   REQUIRE(drawable() && format(), return 0);
  196.  
  197.   return page_->locate(pos, top, bot);
  198. }
  199.  
  200.  
  201. XTextFlow::XTextFlow(TextFlow& parent, TextPosition first, TextPosition last,
  202.              XTextView& view, const CharacterFormat& cf, char c)
  203. : TextFlow(parent, first, last)
  204. {
  205.   view_ = &view;
  206.   c_ = c;
  207.   ul_ = cf.underline;
  208.   super_ = cf.super;
  209.   sub_ = cf.sub;
  210.   static char spec[80];
  211.   static char* faces[] =
  212.     {"nil", "roman", "swiss", "modern", "script", "decor", "tech"};
  213.  
  214.   strcpy(spec, faces[cf.font_family]);
  215.   if(cf.bold)
  216.     strcat(spec, "-bold");
  217.   if(cf.italic)
  218.     strcat(spec, "-italic");
  219. #ifdef FONT_SIZES
  220.   if(cf.size != 24)
  221.     sprintf(spec + strlen(spec), "-%d", cf.size/2);
  222. #endif
  223.  
  224.   font_ = view.font(spec);
  225.  
  226.   XGCValues values;
  227.   unsigned long valuemask;
  228.  
  229.   values.function = GXcopy;
  230.   values.foreground = cf.fg_pixel;
  231.   values.font = font()->fid;
  232.   valuemask = GCFunction | GCForeground | GCFont;
  233.   gc_ = view.get_gc(valuemask, values);
  234. }
  235.  
  236. XTextFlow::~XTextFlow()
  237. {
  238.   view_->free_gc(gc_);
  239. }
  240.  
  241. Qty
  242. XTextFlow::character_shape(TextPosition pos, Qty q,
  243.                Extent avail, Extent& used, int whole)
  244.      const
  245. {
  246.   if(avail.right() - avail.current_x() < 2)
  247.     return 0; // optimization
  248.  
  249.   XCharStruct ext;
  250.   int ascent;
  251.   int descent;
  252.   int dir;
  253.  
  254.   /* for single (escaped) characters */
  255.   if(c_){
  256.     char x = c_; // appease the compiler
  257.     XTextExtents(font(), &x, 1,
  258.          &dir, &ascent, &descent, &ext);
  259.     if(ascent + descent < avail.bottom()-avail.top() &&
  260.        ext.width < avail.right() - avail.current_x()){
  261.       used.x2 = 0; //left over to justify
  262.       ((XTextFlow*)this)->width(used.x0 = ext.width); // get around compiler
  263.       used.y0 = ascent;
  264.       used.y1 = descent;
  265.       return q;
  266.     }else
  267.       return 0;
  268.   }
  269.  
  270.   const Byte* text = data() + pos;
  271.     
  272.   assert(q>0);
  273.   assert(avail.right() >= avail.current_x());
  274.   assert(avail.current_x() >= avail.width());
  275.   assert(avail.right() > avail.width());
  276.  
  277.   /*@# BREAK_CHARS should be a resource */
  278. # define BREAK_CHARS " -"
  279.  
  280.   XTextExtents(font(), (char*)text, (int)q, /* @# int! */
  281.            &dir, &ascent, &descent, &ext);
  282.  
  283.   ascent += super_;
  284.   descent += sub_;
  285.   REQUIRE(ascent + descent <= avail.bottom() - avail.top(),
  286.       return 0);
  287.  
  288.   while(ext.width > avail.right() - avail.current_x()){
  289.     if(whole)
  290.       while(--q>0 && strchr(BREAK_CHARS, text[q-1]) == 0)
  291.     ;
  292.     else
  293.       q--;
  294.     if(q == 0)
  295.       return 0;
  296.     XTextExtents(font(), (char*)text, (int)q, /*@# int! */
  297.          &dir, &ascent, &descent, &ext);
  298.     
  299.   }
  300.  
  301.   used.x2 = 0; //left over to justify
  302.   ((XTextFlow*)this)->width(used.x0 = ext.width); // get around compiler
  303.   used.y0 = ascent;
  304.   used.y1 = descent;
  305.   return q;
  306. }
  307.  
  308. void
  309. XTextFlow::render(TextPosition pos, Qty q, Point p) const
  310. {
  311.   REQUIRE(display() && drawable(), return);
  312.   const Byte* text = data() + pos;
  313.   Coord y = p.y + - super_ + sub_;
  314.  
  315.   if(c_){
  316.     char x = c_; //appease compiler
  317.     XDrawString(display(), drawable(), gc(), p.x, y,
  318.         &x, (int)1);
  319.   }
  320.   else
  321.     XDrawString(display(), drawable(), gc(), p.x, y, (char*)text, (int)q);
  322.  
  323.   // HEURISTIC: underlines 2 pixels below baseline
  324.   if(ul_)
  325.     XDrawLine(display(), drawable(), gc(), p.x, y+2, p.x+width_, y+2);
  326. }
  327.  
  328.  
  329. void
  330. XTextView::picture(TextFlow& p, TextPosition f, TextPosition l,
  331.          Coord w, Coord h)
  332. {
  333.   new XBitMap(p, f, l, *this, w, h);
  334. }
  335.  
  336.  
  337. XBitMap::XBitMap(TextFlow& p, TextPosition f, TextPosition l,
  338.          XTextView& v, int width, int height)
  339.          : TextFlow(p, f, l)
  340. {
  341.   view_ = &v;
  342.   width_ = width;
  343.   height_ = height;
  344.   pixmap_ = None;
  345. }
  346.  
  347. XBitMap::~XBitMap()
  348. {
  349.   if(pixmap_ != None)
  350.     XFreePixmap(view_->display(), pixmap_);
  351. }
  352.  
  353. Qty
  354. XBitMap::character_shape(TextPosition, Qty q,
  355.              Extent avail, Extent& used, int) const
  356. {
  357.   if(avail.right() - avail.current_x() < width_
  358.      || avail.bottom() - avail.top() < height_)
  359.     return 0;
  360.  
  361.   used.x0 = width_;
  362.   used.x2 = 0;
  363.   used.ascent(height_);
  364.   used.descent(0);
  365.   return q;
  366. }
  367.  
  368. int
  369. XBitMap::get_pixmap()
  370. {
  371.   static builder_inited = 0;
  372.   if(!builder_inited){
  373.     if(!initializeImageBuilder(view_->display()))
  374.       return 0;
  375.     builder_inited = 1;
  376.   }    
  377.  
  378.   if(pixmap_ != None)
  379.     return 1;
  380.   else if(pixmap_ = createPixmapFromHexData(view_->display(),
  381.                         view_->drawable(),
  382.                         (const char*)data()))
  383.     return 1;
  384.   else
  385.     return 0;
  386. }
  387.  
  388. void
  389. XBitMap::render(TextPosition, Qty, Point p) const
  390. {
  391.   if(((XBitMap*)this)->get_pixmap()) // appease compiler
  392.     //@@ don't copy the whole thing! just the exposed parts.
  393.     //@@ unfortunately, we don't have that info here.
  394.     XCopyArea(view_->display(), pixmap_, view_->drawable(),
  395.           view_->default_gc(), 0, 0, width_, height_, p.x, p.y - height_);
  396. }
  397.  
  398.